package com.codejiwei.flink.broadcast;

/**
 * author: codejiwei
 * date: 2023/8/2
 * desc:
 **/

import java.util.*;


public class JsonUtil {
    /**
     * 解析map为jsonString
     * @param map
     * @return
     */
    public static String encode(Map<?,?> map){
        if (map == null) {
            return null;
        }
        Iterator<?> it = map.keySet().iterator();
        StringBuffer sb = new StringBuffer("{");
        while(it.hasNext()){
            Object b = it.next();
            Object v = map.get(b);
            sb.append("\"").append(b).append("\":").append(encodeJson(v)).append(",");
        }
        if(sb.length()>1){
            sb.deleteCharAt(sb.length()-1);
        }
        sb.append("}");
        return sb.toString();
    }

    /**
     * 解析list为jsonString
     * @param list
     * @return
     */
    public static String encode(List<?> list){
        if (list == null) {
            return null;
        }
        StringBuffer sb = new StringBuffer("[");
        for(Object v:list){
            sb.append(encodeJson(v)).append(",");
        }
        if(sb.length()>1){
            sb.deleteCharAt(sb.length()-1);
        }
        sb.append("]");
        return sb.toString();
    }

    /**
     * 将object转换成jsonstring
     * @param b
     * @return
     */
    public static String encodeJson(Object b){
        if (b == null) {
            return "\"\"";
        }else if(b instanceof Map){
            return encode((Map<?, ?>) b);
        }else if(b instanceof List){
            return encode((List<?>) b);
        }else if(b instanceof Number){
            return b+"";
        }else if(b instanceof String){
            b = ((String)b).replace("\\", "\\\\").replace("\"", "\\\"");
            return "\""+(String)b+"\"";
        }else{
            return "\""+b.toString()+"\"";
        }
    }
    /**
     * 解析jsonstring为object,目前支持Map和List的转换
     * @param text
     */
    public static Map<String, Object> decode(String text){
        Map<String, Object> a=new LinkedHashMap<String, Object>();
        if(text==null || text.toLowerCase().equals("null")){
            return a;
        }
        text = text.trim();
        if(text == "" || text.length()<=0){
            return a;
        }
        dealQueue(a, find(text));
        return a;
    }

    /**
     * 处理分隔好的jsonString
     * @param a
     * @param queue
     */
    @SuppressWarnings("unchecked")
    private static void dealQueue(Object a,LinkedList<String> queue){
        while(!queue.isEmpty()){
            String c=queue.poll();
            if("{".equals(c)){
                if(a instanceof List){
                    Map<String, Object> l = new LinkedHashMap<String, Object>();
                    dealQueue(l,queue);
                    ((List<Object>) a).add(l);
                }else{
                    dealQueue(a,queue);
                }
            }else if("[".equals(c)){
                dealQueue(a,queue);
            }else if(("]".equals(c) || "}".equals(c))){
                break;
            }else{
                if(a instanceof Map){
                    String d=queue.poll();
                    Object f;
                    if (d == null) {
                        ((Map<String, Object>) a).put(c, d);
                    } else if("{".equals(d)){
                        f = new LinkedHashMap<String, Object>();
                        dealQueue(f,queue);
                        ((Map<String, Object>)a).put(c, f);
                    }else if("[".equals(d)){
                        f = new ArrayList<Object>();
                        dealQueue(f,queue);
                        ((Map<String, Object>)a).put(c, f);
                    }else{
                        ((Map<String, Object>)a).put(c, d);
                    }
                }else if(a instanceof List){
                    ((List<Object>)a).add(c);
                }
            }
        }
    }

    /**
     * 将jsonString进行分隔
     * @param text
     * @return
     */
    private static LinkedList<String> find(String text){
        char[] src = text.trim().toCharArray();
        LinkedList<String> queue = new LinkedList<String>();
        String s="",temp=null;
        int len=src.length;
        int start=0;
        while(start<len){
            switch(src[start]){
                case ' ':
                    start++;
                    break;
                case '{':
                case '}':
                case '[':
                case ']':
                    queue.add(src[start]+"");
                    start++;
                    break;
                case ':':
                    if(start - 1 > 0 && (src[start - 1] == ',' || src[start - 1] == '}'|| src[start - 1] == ']'|| src[start - 1] == '{'|| src[start - 1] == '[')){
                        queue.add(null);
                    }
                    if (start + 1 < len && (src[start + 1] == ',' || src[start + 1] == '}')) {
                        queue.add(null);
                        start++;
                        break;
                    }
                case ',':
                    start++;
                    break;
                case '\"':
                    int j=start+1;
                    char[] ch = new char[len-start];
                    int k=0;
                    while(j<len){
                        if(src[j]=='\\'){
                            //unicode编码转换，\开始的6个字符形式如同\u8e03
                            if(j + 5 < len && src[j+1] == 'u'){
                                temp = new String(src, j + 2, 4);
                                if(temp.matches("^[0-9a-fA-F]{4}$")){
                                    j += 6;
                                    ch[k++]=(char)Integer.parseInt(temp,16);
                                    continue;
                                }
                            }
                            j++;//其他跳过\转义
                            ch[k++]=src[j];
                        }else if(src[j]=='\"'){
                            j++;
                            break;
                        }else{
                            ch[k++]=src[j];
                        }
                        j++;
                    }
                    s=new String(ch,0,k);
                    if("[".equals(s) || "{".equals(s) ||"]".equals(s) || "}".equals(s)){
                        s+=" ";
                    }
                    queue.add(s);
                    start=j;
                    break;
                default:
                    j=start+1;
                    while(j<len){
                        if(src[j]==':'||src[j]==']'||src[j]=='}'||src[j]==','){
                            break;
                        }
                        j++;
                    }
                    queue.add(text.substring(start,j));
                    start=j;
                    break;
            }
        }
        return queue;
    }
}


